package com.five.monkey.feign.provider.controller;

import com.five.monkey.feign.provider.lock.Lock;
import com.five.monkey.feign.provider.lock.LockService;
import com.five.monkey.vo.CommonVo;
import com.five.monkey.vo.TestVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author 狻猊
 * @date 2021/10/9 4:06 下午
 */
@RestController
@RequestMapping("/test")
public class TestController {

    private static final Logger logger = LoggerFactory.getLogger(TestController.class);

    @Autowired
    private LockService zkLockService;

    /**
     * 无限等待直到获得锁-测试
     */
    @GetMapping("/zkLock")
    public CommonVo<TestVo> zkLockTest(@RequestParam("name") String name) {
        TestVo vo = new TestVo();
        vo.setName(name);
        Lock lock = zkLockService.getLock("zkLockTest");
        try {
            if (lock.acquire()) {
                vo.setAge(new Random().nextInt());
                vo.setScore(new Random().nextFloat());
                logger.info("name={},加锁成功,正在sleep中......", name);
                TimeUnit.SECONDS.sleep(10);
            }
        } catch (InterruptedException e) {
            logger.error("test zkLock error", e);
        } finally {
            lock.release();
            logger.info("name={},释放锁成功", name);
        }
        return CommonVo.ok(vo);
    }

    /**
     * 等待超时获取锁失败-测试
     */
    @GetMapping("/time/zkLock")
    public CommonVo<TestVo> timeZkLockTest(@RequestParam("name") String name) {
        TestVo vo = new TestVo();
        vo.setName(name);
        Lock lock = zkLockService.getLock("zkLockTest");
        try {
            if (lock.acquire(3L, TimeUnit.SECONDS)) {
                vo.setAge(new Random().nextInt());
                vo.setScore(new Random().nextFloat());
                logger.info("name={},加锁成功,正在sleep中......", name);
                TimeUnit.SECONDS.sleep(10);
            }
        } catch (InterruptedException e) {
            logger.error("test zkLock error", e);
        } finally {
            lock.release();
            logger.info("name={},释放锁成功", name);
        }
        return CommonVo.ok(vo);
    }

    /**
     * 不等待获取锁失败-测试
     */
    @GetMapping("/not/wait/zkLock")
    public CommonVo<TestVo> notWaitZkLockTest(@RequestParam("name") String name) {
        TestVo vo = new TestVo();
        vo.setName(name);
        Lock lock = zkLockService.getLock("zkLockTest");
        try {
            if (lock.acquireNotWait()) {
                vo.setAge(new Random().nextInt());
                vo.setScore(new Random().nextFloat());
                logger.info("name={},加锁成功,正在sleep中......", name);
                TimeUnit.SECONDS.sleep(10);
            }
        } catch (InterruptedException e) {
            logger.error("test zkLock error", e);
        } finally {
            lock.release();
            logger.info("name={},释放锁成功", name);
        }
        return CommonVo.ok(vo);
    }
}
